package cn.gwm.flink.streaming.strategy.cloudpredict;

import cn.gwm.flink.streaming.constant.ChargePredictFields;
import cn.gwm.flink.streaming.strategy.vehiclepredict.DwsStrConstant;
import cn.gwm.utils.HBaseDataSource;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.api.common.state.MapState;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * @author : GW00280745
 * @date : 2023/6/15 15:34
 * @description :
 */
public class CloudDefaultVal {
    /**
     *
     * @param line
     * @return 获取经验值
     */
    public  String process(JSONObject line){
//        String s = predict2(line);
//        if (StringUtils.isNotBlank(s)){
//            return s;
//        }
        //V2 同车同aoipoi且充电时间最长的
//        String s = process2(line);
//        if (StringUtils.isBlank(s)){
//            s = process3(line);
//        }
//        if (StringUtils.isBlank(s)){
//            s = process4(line);
//        }
//        return s;
        //V3 同车同温度同经纬度且充电时间top3的均值
        String s = process5(line);
        if (StringUtils.isBlank(s)){
            s = process4(line);
        }
        return s;
    }

    private String process5(JSONObject line) {
        Connection connection = null;
        try {
            //select id,"slicetime_avg" from "vaas_dws"."dws_charge_detail_default_obc" where id='';
            //concat(deviceid,':',bms_rmc_moduletempmin,':',longitude,':',latitude) as rk,
            String vin = line.getString(ChargePredictFields.ins().srcFieldVin);
            Float tempMin = line.getFloat(ChargePredictFields.ins().srcFieldBmsRmcModuleTempMin);
            String longtitude = line.getString(ChargePredictFields.ins().srcFieldLongitude);
            String latitude = line.getString(ChargePredictFields.ins().srcFieldLatitude);
            // 同车历史中充电时间最长的样本再乘以系数
            String rkLow = vin.concat(ChargePredictFields.ins().colon)
                    .concat(String.valueOf((int)(tempMin-2)))
                    ;
            String rkHigh = vin.concat(ChargePredictFields.ins().colon)
                    .concat(String.valueOf((int)(tempMin+2)))
                    ;
            String sqlBef="select id,\"slicetime_avg\" from \"vaas_dws\".\"dws_charge_detail_default_obc\" where id>='%s' and id<='%s' ";
            String sql = String.format(sqlBef, rkLow,rkHigh);
            System.out.println(String.format("chargeId=%s ,sql --> %s ",chargeIdName(line),sql));
            connection = HBaseDataSource.ins().getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet rs = null;
            try {
                rs = preparedStatement.executeQuery();
            }catch (Exception e){
                //第一次如果报错了，那么就重试一次，如果还是错误先跳过
                rs = preparedStatement.executeQuery();
            }
            int cnt =0;
            float t=0;
            while (rs.next()) {
                String id = rs.getString(1);
                String[] split = id.split(ChargePredictFields.ins().colon);
                String tid = split[0];
                String temp = split[1];
                String longVal = split[2];
                String latVal = split[3];
                //
                if (!StringUtils.equalsIgnoreCase(longtitude,ChargePredictFields.ins().defaultVal)){
                    float lv = Float.parseFloat(longVal);
                    float v1 = new BigDecimal(Float.parseFloat(longtitude) - 0.001).setScale(3, BigDecimal.ROUND_HALF_UP).floatValue();
                    float v2 = new BigDecimal(Float.parseFloat(longtitude) + 0.001).setScale(3, BigDecimal.ROUND_HALF_UP).floatValue();
                    boolean b = lv >= v1 && lv <= v2;
                    if (!b){
                        continue;
                    }
                }
                if (!StringUtils.equalsIgnoreCase(latitude,ChargePredictFields.ins().defaultVal)){
                    float lv = Float.parseFloat(latVal);
                    float v1 = new BigDecimal(Float.parseFloat(latitude) - 0.001).setScale(3, BigDecimal.ROUND_HALF_UP).floatValue();
                    float v2 = new BigDecimal(Float.parseFloat(latitude) + 0.001).setScale(3, BigDecimal.ROUND_HALF_UP).floatValue();
                    boolean b = lv >= v1 && lv <= v2;
                    if (!b){
                        continue;
                    }
                }
                String sliceTimeAvg = rs.getString(2);
                if (StringUtils.isBlank(sliceTimeAvg)){
                    continue;
                }
                t+=Float.parseFloat(sliceTimeAvg);
                cnt++;
            }
            if(cnt==0){
                return null;
            }
            float timeF = t/cnt;
            String soc = line.getString(ChargePredictFields.ins().srcFieldBmsSoc);
            System.out.println(String.format("chargeId=%s ,default_match-process2 ---> timeF  =%s , soc = %s",chargeIdName(line),timeF,soc));
            timeF = curr2SliceTime(line,timeF);
            int i = new BigDecimal(timeF*(100-Float.parseFloat(soc))).divide(new BigDecimal(60), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
            if (i>DwsStrConstant.ins().timeLim){
                //起始点的充电时长不能太长
                i =DwsStrConstant.ins().timeLim;
                System.out.println(String.format("chargeId=%s ,cal_first-process2 --->  time > 1200 ",chargeIdName(line)));
            }
            String concat = soc.concat(ChargePredictFields.ins().char3).concat("100").concat(ChargePredictFields.ins().char3).concat(String.valueOf(i));
            System.out.println(String.format("chargeId=%s ,cal_first_default-process2 --->  time=%s ,timeF*(100-soc) =%s,%s",chargeIdName(line),concat,timeF,soc));
            return concat;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            HBaseDataSource.ins().close(connection);
        }
        return null;
    }
    private String process4(JSONObject line) {
        try {
            Float curr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            float abs = Math.abs(curr);
            float timeF = 320;
            if (abs <8 ){
                timeF = 720 ;
            }else if(abs<20){
                timeF = 330 ;
            }
            String soc = line.getString(ChargePredictFields.ins().srcFieldBmsSoc);
            int i = new BigDecimal(timeF*(100-Float.parseFloat(soc))).divide(new BigDecimal(60), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
            if (i>DwsStrConstant.ins().timeLim){
                //起始点的充电时长不能太长
                i =DwsStrConstant.ins().timeLim;
                System.out.println(String.format("chargeId=%s ,cal_first-process4 --->  time > 1200 ",chargeIdName(line)));
            }
            String concat = soc.concat(ChargePredictFields.ins().char3).concat("100").concat(ChargePredictFields.ins().char3).concat(String.valueOf(i));
            System.out.println(String.format("chargeId=%s ,cal_first_default ,process4 --->  time=%s ,timeF*(100-soc) =%s,%s",chargeIdName(line),concat,timeF,soc));
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public  String process2(JSONObject line){
        Connection connection = null;
        try {
            //select id,"slicetime_avg" from "vaas_dws"."dws_charge_detail_default_obc" where id='';
            //concat(model_code,bms_innersoc,bms_battcurr_rm)
            String modelCode = line.getString(ChargePredictFields.ins().srcFieldModelCode);
            String soc = line.getString(ChargePredictFields.ins().srcFieldBmsSoc);
            Float bmsCurr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            String poiId = line.getString(ChargePredictFields.ins().srcFieldPoiId);
            String aoiId = line.getString(ChargePredictFields.ins().srcFieldAoiId);
            String vin = line.getString(ChargePredictFields.ins().srcFieldVin);
//            String rk = modelCode.concat(soc2group(line)).concat(curr2group(line));
            // 同车历史中充电时间最长的样本再乘以系数
            String rk = vin.concat(poiId).concat(aoiId);
            String sqlBef="select id,\"slicetime_avg\" from \"vaas_dws\".\"dws_charge_detail_default_obc\" where id='%s'";
            String sql = String.format(sqlBef, rk);
            System.out.println(String.format("chargeId=%s ,sql --> %s ",chargeIdName(line),sql));
            connection = HBaseDataSource.ins().getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet rs = null;
            try {
                rs = preparedStatement.executeQuery();
            }catch (Exception e){
                //第一次如果报错了，那么就重试一次，如果还是错误先跳过
                rs = preparedStatement.executeQuery();
            }
            String sliceTimeAvg = null;
            while (rs.next()) {
                String deviceId = rs.getString(1);
                sliceTimeAvg = rs.getString(2);
            }
            if(StringUtils.isBlank(sliceTimeAvg)){

                return null;
            }
            float timeF = Float.parseFloat(sliceTimeAvg);
            System.out.println(String.format("chargeId=%s ,default_match-process2 ---> timeF  =%s , soc = %s",chargeIdName(line),timeF,soc));
            timeF = curr2SliceTime(line,timeF);
            int i = new BigDecimal(timeF*(100-Float.parseFloat(soc))).divide(new BigDecimal(60), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
            if (i>DwsStrConstant.ins().timeLim){
                //起始点的充电时长不能太长
                i =DwsStrConstant.ins().timeLim;
                System.out.println(String.format("chargeId=%s ,cal_first-process2 --->  time > 1200 ",chargeIdName(line)));
            }
            String concat = soc.concat(ChargePredictFields.ins().char3).concat("100").concat(ChargePredictFields.ins().char3).concat(String.valueOf(i));
            System.out.println(String.format("chargeId=%s ,cal_first_default-process2 --->  time=%s ,timeF*(100-soc) =%s,%s",chargeIdName(line),concat,timeF,soc));
            return concat;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            HBaseDataSource.ins().close(connection);
        }
        return null;
    }
    public  String process3(JSONObject line){
        Connection connection = null;
        try {
            //select id,"slicetime_avg" from "vaas_dws"."dws_charge_detail_default_obc" where id='';
            //concat(model_code,bms_innersoc,bms_battcurr_rm)
            String modelCode = line.getString(ChargePredictFields.ins().srcFieldModelCode);
            String soc = line.getString(ChargePredictFields.ins().srcFieldBmsSoc);
            Float bmsCurr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            String poiId = line.getString(ChargePredictFields.ins().srcFieldPoiId);
            String aoiId = line.getString(ChargePredictFields.ins().srcFieldAoiId);
            String vin = line.getString(ChargePredictFields.ins().srcFieldVin);
//            String rk = modelCode.concat(soc2group(line)).concat(curr2group(line));
            // 同车历史中充电时间最长的样本再乘以系数
            String rk = vin.concat(poiId).concat(aoiId);
            String sqlBef="select id,\"slicetime_avg\" from \"vaas_dws\".\"dws_charge_detail_default_obc\" where id like '" +vin+
                    "%'";
            String sql = sqlBef;
            System.out.println(String.format("chargeId=%s ,sql --> %s ",chargeIdName(line),sql));
            connection = HBaseDataSource.ins().getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet rs = null;
            try {
                rs = preparedStatement.executeQuery();
            }catch (Exception e){
                //第一次如果报错了，那么就重试一次，如果还是错误先跳过
                rs = preparedStatement.executeQuery();
            }
            String sliceTimeAvg = null;
            while (rs.next()) {
                String deviceId = rs.getString(1);
                sliceTimeAvg = rs.getString(2);
                break;
            }
            if(StringUtils.isBlank(sliceTimeAvg)){
                return null;
            }
            float timeF = Float.parseFloat(sliceTimeAvg);
            System.out.println(String.format("chargeId=%s ,default_match-process3 ---> timeF_src  =%s , soc = %s",chargeIdName(line),timeF,soc));
            timeF = curr2SliceTime(line,timeF);
            int i = new BigDecimal(timeF*(100-Float.parseFloat(soc))).divide(new BigDecimal(60), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
            if (i>DwsStrConstant.ins().timeLim){
                //起始点的充电时长不能太长
                i =DwsStrConstant.ins().timeLim;
                System.out.println(String.format("chargeId=%s ,cal_first-process3 --->  time > 1200 ",chargeIdName(line)));
            }
            String concat = soc.concat(ChargePredictFields.ins().char3).concat("100").concat(ChargePredictFields.ins().char3).concat(String.valueOf(i));
            System.out.println(String.format("chargeId=%s ,cal_first_default-process3 --->  time=%s ,timeF*(100-soc) =%s,%s",chargeIdName(line),concat,timeF,soc));
            return concat;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            HBaseDataSource.ins().close(connection);
        }
        return null;
    }
    private Float curr2SliceTime(JSONObject line,float time){
//        try {
//            Float bmsCurr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
//            float abs = Math.abs(bmsCurr);
//            //如果电流小于8A 则平均时间应该在
//            if(abs <= 7.9){
//                if (time<500){
//                    return  780f;
//                }
//            }else if ( abs>=9 && abs <= 10){
//                // 时间应该在10分钟 大概600s 上下加减200s
//                if (time <400){
//                    return 540f;
//                }else if (time > 800){
//                    return 540f;
//                }
//            }else if ( abs>=11 && abs <= 12){
//                // 时间应该在8分钟 大概480s 上下加减100s
//                if (time <300){
//                    return 470f;
//                }else if (time > 600){
//                    return 470f;
//                }
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
        return time;
    }
    private String chargeIdName(JSONObject line){
        String vin = line.getString(ChargePredictFields.ins().srcFieldVin);
        String startChargeTime = line.getString(ChargePredictFields.ins().srcFieldStartChargeTime);
        String chargeId = vin.concat(startChargeTime);
        return chargeId;
    }
    public String predict2(JSONObject line){
        try {

            String modelCode = line.getString(ChargePredictFields.ins().srcFieldModelCode);
            if (StringUtils.isBlank(modelCode) || StringUtils.equalsIgnoreCase(modelCode,ChargePredictFields.ins().defaultVal)){
            }
            float packCapacity = 0;
            if (StringUtils.equalsIgnoreCase(modelCode,"CC7000CG00ABEV")){
                packCapacity = 156;
            }else if(StringUtils.equalsIgnoreCase(modelCode,"CC7000CG01ABEV")){
                packCapacity = 179;
            }else {
                return null;
            }
            if (packCapacity==0){
            }
            Float curr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            float abs = Math.abs(curr);
            int fenmu = 7;
            if (abs<=10){
                fenmu = 7;
            }else if (abs <= 15){
                fenmu = 13;
            }else if (abs <=20){
                fenmu = 18;
            }else {
                return null;
            }
            float socSliceTime =(packCapacity / fenmu) / 100 * 60  ;
            Float soc = line.getFloat(ChargePredictFields.ins().srcFieldBmsSoc);
            int i = new BigDecimal(socSliceTime*(100-soc)*0.95).divide(new BigDecimal(1), 0, BigDecimal.ROUND_HALF_DOWN).abs().intValue();
            System.out.println(String.format("model_ocde=%s ,pack_capatity= %s ,curr = %s, soc=%s ,time =%s ",modelCode,packCapacity,curr,soc,i));
            String concat = soc.toString().concat(ChargePredictFields.ins().char3).concat("100").concat(ChargePredictFields.ins().char3).concat(String.valueOf(i));
            return concat;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    private String soc2group(JSONObject line){
        try {
            Float soc = line.getFloat(ChargePredictFields.ins().srcFieldBmsSoc);
            if (soc<= DwsStrConstant.ins().num10){
                return "10";
            }else if(soc<=DwsStrConstant.ins().num20){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num30){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num40){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num50){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num60){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num70){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num80){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num90){
                return "20";
            }else if(soc<=DwsStrConstant.ins().num100){
                return "20";
            }else {
                return ChargePredictFields.ins().defaultVal;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return "null";
    }
    private String curr2group(JSONObject line){
        try {
            Float bmsCurr = line.getFloat(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            if (bmsCurr>=DwsStrConstant.ins().numF10){
                return "-10";
            }else if (bmsCurr>=DwsStrConstant.ins().numF20){
                return "-20";
            }else if (bmsCurr>=DwsStrConstant.ins().numF100){
                return "-100";
            }else if (bmsCurr < DwsStrConstant.ins().numF100){
                return "-200";
            }else{
                return ChargePredictFields.ins().defaultVal;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return "null";
    }
}
